package org.internna.ossmoney.services.impl;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.internna.ossmoney.model.Widget;
import org.internna.ossmoney.model.Category;
import org.internna.ossmoney.model.Dashboard;
import org.internna.ossmoney.model.Subcategory;
import org.internna.ossmoney.model.budget.Budget;
import org.internna.ossmoney.services.AdminService;
import org.internna.ossmoney.model.security.Authority;
import org.internna.ossmoney.model.security.UserDetails;
import org.internna.ossmoney.model.budget.MonthlyBudget;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

@Transactional
public final class UserService implements org.internna.ossmoney.services.UserService {

	private static final Log logger = LogFactory.getLog(UserService.class);

	@Autowired private AdminService adminService;

	private String salt;
	private boolean createBasicSpanishFinancialInstitutions = true;

	public void setSalt(String salt) {
		this.salt = salt;
	}

	public void setCreateBasicSpanishFinancialInstitutions(boolean createBasicSpanishFinancialInstitutions) {
		this.createBasicSpanishFinancialInstitutions = createBasicSpanishFinancialInstitutions;
	}

	@Override public void register(String username, String password, String name, String email) {
		createUser(username, password, name, email, createDashBoDashboard());
		logger.info("Registered new user[" + username + "]");
	}

	protected UserDetails createUser(String username, String password, String name, String email, Dashboard dashboard) {
		Authority authority = Authority.findByName(Authority.ROLE_USER);
		UserDetails user = new UserDetails();
		user.setSalt(salt);
		user.setName(name);
		user.setEmail(email);
		user.setUsername(username);
		user.setPassword(password);
		user.setDashboard(dashboard);
		user.setEnabled(Boolean.TRUE);
		user.getRoles().add(authority);
		authority.getUsers().add(user);
		user.persist();
		adminService.createPayee(user, user.getName());
		createSubcategories(user);
		user.setBudget(createBudget(user));
		if (createBasicSpanishFinancialInstitutions) {
			createBasicSpanishInstitutions(user);
		}
		authority.merge();
		user.merge();
		return user;
	}

	protected void createSubcategories(UserDetails user) {
		Category transferIn = Category.findCategory(2L);
		Category transferOut = Category.findCategory(1L);
		Category investmentIn = Category.findCategory(4L);
		Category investmentOut = Category.findCategory(3L);
		Category financial = Category.findByCategory("category.financial");
		Category household = Category.findByCategory("category.household");
		Category leisure = Category.findByCategory("category.leisure");
		Category salary = Category.findByCategory("category.salary");
		Category automobile = Category.findByCategory("category.automobile");
		Category bills = Category.findByCategory("category.bills");
		Category healthcare = Category.findByCategory("category.healthcare");
		Category taxesIn = Category.findCategory(13L);
		Category taxesOut = Category.findCategory(12L);
		Category travel = Category.findByCategory("category.travel");
		Category sporadic = Category.findByCategory("category.sporadic");
		Category personal = Category.findByCategory("category.personal");
		Category children = Category.findByCategory("category.children");
		Category pet = Category.findByCategory("category.pet");

		Subcategory.createInstance("category.transfer.out", transferOut, user);
		Subcategory.createInstance("category.transfer.in", transferIn, user);
		Subcategory.createInstance("category.cc.payment.out", transferOut, user);
		Subcategory.createInstance("category.cc.payment.in", transferIn, user);
		Subcategory.createInstance("category.investment.buy", investmentOut, user);
		Subcategory.createInstance("category.investment.sell", investmentIn, user);
		Subcategory.createInstance("category.investment.interest", investmentIn, user);
		Subcategory.createInstance("category.bankcharges", financial, user);
		Subcategory.createInstance("category.interestpaid", financial, user);
		Subcategory.createInstance("category.mortgage", financial, user);
		Subcategory.createInstance("category.furnishing", household, user);
		Subcategory.createInstance("category.improvement", household, user);
		Subcategory.createInstance("category.dues", household, user);
		Subcategory.createInstance("category.cleaning", household, user);
		Subcategory.createInstance("category.rent", household, user);
		Subcategory.createInstance("category.yard", household, user);
		Subcategory.createInstance("category.homeinsurance", household, user);
		Subcategory.createInstance("category.restaurant", leisure, user);
		Subcategory.createInstance("category.cinema", leisure, user);
		Subcategory.createInstance("category.videogames", leisure, user);
		Subcategory.createInstance("category.books", leisure, user);
		Subcategory.createInstance("category.movies", leisure, user);
		Subcategory.createInstance("category.sports", leisure, user);
		Subcategory.createInstance("category.music", leisure, user);
		Subcategory.createInstance("category.casino", leisure, user);
		Subcategory.createInstance("category.wages", salary, user);
		Subcategory.createInstance("category.gross", salary, user);
		Subcategory.createInstance("category.bonus", salary, user);
		Subcategory.createInstance("category.overtime", salary, user);
		Subcategory.createInstance("category.allowance", salary, user);
		Subcategory.createInstance("category.allowance", automobile, user);
		Subcategory.createInstance("category.carpayment", automobile, user);
		Subcategory.createInstance("category.gasoline", automobile, user);
		Subcategory.createInstance("category.insurance", automobile, user);
		Subcategory.createInstance("category.maintenance", automobile, user);
		Subcategory.createInstance("category.tv", bills, user);
		Subcategory.createInstance("category.phone", bills, user);
		Subcategory.createInstance("category.cellphone", bills, user);
		Subcategory.createInstance("category.electricity", bills, user);
		Subcategory.createInstance("category.garbage", bills, user);
		Subcategory.createInstance("category.gym", bills, user);
		Subcategory.createInstance("category.membership", bills, user);
		Subcategory.createInstance("category.gas", bills, user);
		Subcategory.createInstance("category.newspaper", bills, user);
		Subcategory.createInstance("category.internet", bills, user);
		Subcategory.createInstance("category.water", bills, user);
		Subcategory.createInstance("category.hospital", healthcare, user);
		Subcategory.createInstance("category.dental", healthcare, user);
		Subcategory.createInstance("category.eyes", healthcare, user);
		Subcategory.createInstance("category.medical", healthcare, user);
		Subcategory.createInstance("category.drugs", healthcare, user);
		Subcategory.createInstance("category.insurance", healthcare, user);
		Subcategory.createInstance("category.personalcare", healthcare, user);
		Subcategory.createInstance("category.federal", taxesOut, user);
		Subcategory.createInstance("category.realestate", taxesOut, user);
		Subcategory.createInstance("category.taxesautomobile", taxesOut, user);
		Subcategory.createInstance("category.ss", taxesOut, user);
		Subcategory.createInstance("category.renttaxes", taxesOut, user);
		Subcategory.createInstance("category.deduction", taxesIn, user);
		Subcategory.createInstance("category.vacation", travel, user);
		Subcategory.createInstance("category.tickets", travel, user);
		Subcategory.createInstance("category.hotel", travel, user);
		Subcategory.createInstance("category.gifts", sporadic, user);
		Subcategory.createInstance("category.donations", sporadic, user);
		Subcategory.createInstance("category.clothing", personal, user);
		Subcategory.createInstance("category.food", personal, user);
		Subcategory.createInstance("category.supplies", personal, user);
		Subcategory.createInstance("category.daycare", children, user);
		Subcategory.createInstance("category.toys", children, user);
		Subcategory.createInstance("category.food", pet, user);
		Subcategory.createInstance("category.supplies", pet, user);
		Subcategory.createInstance("category.veterinarian", pet, user);
	}

	protected Dashboard createDashBoDashboard() {
		Dashboard dashboard = new Dashboard();
		dashboard.setColumns(3);
		dashboard.persist();
		Widget widget = Widget.createInstance("accounts.favorites.title", 1, 1, "/financial/accounts/favorites", null);
		dashboard.addWidget(widget);
		widget.persist();
		widget = Widget.createInstance("widgets.remainder.title", 1, 2, "/financial/widgets/remainder/", "30");
		dashboard.addWidget(widget);
		widget.persist();
		widget = Widget.createInstance("widgets.networth.title", 1, 3, "/financial/widgets/networth/", "5");
		dashboard.addWidget(widget);
		widget.persist();
		widget = Widget.createInstance("budget.widget.title", 2, 1, "/financial/budget/graph/", "expanded");
		dashboard.addWidget(widget);
		widget.persist();
		widget = Widget.createInstance("accounts.expensesbycategory.dashtitle", 2, 2, "/financial/widgets/expenses_by_category/", "last_quarter");
		dashboard.addWidget(widget);
		widget.persist();
		widget = Widget.createInstance("accounts.expensesovertime.title", 2, 3, "/financial/widgets/expenses_over_time/", "5");
		dashboard.addWidget(widget);
		widget.persist();
		widget = Widget.createInstance("accounts.incomevsexpenses.title", 3, 1, "/financial/widgets/income_vs_expenses/", "previous_month");
		dashboard.addWidget(widget);
		widget.persist();
		widget = Widget.createInstance("widgets.incomevsexpensesovertime.title", 3, 2, "/financial/widgets/income_vs_expenses_over_time/", "11");
		dashboard.addWidget(widget);
		widget.persist();
		dashboard.merge();
		return dashboard;
	}

	protected Budget createBudget(UserDetails user) {
		Budget budget = new Budget();
		budget.setOwner(user);
		budget.persist();
		for (int i = 0; i < 12; i++) {
			MonthlyBudget monthlyBudget = new MonthlyBudget();
			monthlyBudget.setBudget(budget);
			monthlyBudget.setBudgetedMonth(i);
			monthlyBudget.persist();
			budget.getMonthlyBudgets().add(monthlyBudget);
		}
		budget.merge();
		return budget;
	}

	protected void createBasicSpanishInstitutions(UserDetails user) {
		adminService.createInstitution(user, "Banco Popular", "http://www.bancopopular.es", "http://depositos.com.es/imagenes/2008/11/bancopopular.jpg");
		adminService.createInstitution(user, "Banco Popular-e", "http://www.bancopopular-e.com", "http://www.bancopopular-e.com/esp/ecom/pc/pweb/bin/img/ecom_logo.gif");
		adminService.createInstitution(user, "Bankinter", "https://www.ebankinter.com", "https://www.bankinter.com/www/cacheables/img/bankinter.v1.cache.gif");
		adminService.createInstitution(user, "iBanesto", "http://www.ibanesto.com", "http://ibanesto.mobi/images/logo_banesto.jpg");
		adminService.createInstitution(user, "ING Direct", "http://www.ingdirect.es/", "http://www.ingdirect.es/home/images/logo.gif");
	}

}
